package crew.blt.handsound.client.mvc.view.crud.user;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.uibinder.client.UiTemplate;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.PasswordTextBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;

import crew.blt.handsound.client.mvc.model.Model;
import crew.blt.handsound.client.services.user.UserService;
import crew.blt.handsound.client.services.user.UserServiceAsync;
import crew.blt.handsound.client.widgets.AuthTypeListBox;
import crew.blt.handsound.shared.domain.Auth;
import crew.blt.handsound.shared.domain.AuthType;
import crew.blt.handsound.shared.domain.User;
import crew.gwt.client.message.ServicesMessages;
import crew.gwt.client.services.util.ServerCall;
import crew.gwt.client.widgets.EntityContainer;
import crew.gwt.client.widgets.MessagePopupPanel;

public class EditUserPage <M extends Model> extends IEditUserPage<M>{

	private final ServicesMessages servicesMessages = GWT.create(ServicesMessages.class);
	private final UserServiceAsync userService = GWT.create(UserService.class);

	@UiTemplate("EditUserPage.ui.xml")
	interface EditUserPageUIBinder extends UiBinder<Widget, EditUserPage> {}
	private static EditUserPageUIBinder uiBinder = GWT.create(EditUserPageUIBinder.class);

	//Search
	@UiField TextBox searchUsername;
	@UiField Button searchBt;
	//Attributes
	@UiField TextBox username;
	@UiField TextBox firstname;
	@UiField TextBox lastname;
	@UiField PasswordTextBox password;
	@UiField Button changePwBt;
	@UiField TextBox address;
	@UiField CheckBox enabled;
	//Auth
	@UiField AuthTypeListBox listAllAuth;
	@UiField EntityContainer<Auth> listUserAuth;
	@UiField Button addAuthBt;
	@UiField Button rmAuthBt;
	//Promotion
	//@UiField PromotionListBox promotionLb;
	
	private User foundUser;
	
	/**
	 * Constructor
	 */
	public EditUserPage() {
	    initWidget(uiBinder.createAndBindUi(this));
	}
	
	@Override
	public Widget getWidgetPage() {
		return this;
	}

	@Override
	public void setUser(User user) {
	}


	//---------------------------------------------------------------------
	//-------------------------- UI action
	public void fillUserPanel(User user) {
		username.setText(user.getUsername());
		lastname.setText(user.getLastName());
		firstname.setText(user.getUsername());
		password.setText (user.getPassword());
		address.setText(user.getEmail());
		enabled.setValue(user.isEnabled());
//		promotionLb.setSelectedPromotion(user.getPromotion());
		
		listUserAuth.clear();
		for(Auth right : user.getAuths()){
			listUserAuth.addEntity(right);
		}
	}
	
	//---------------------------------------------------------------------
	//-------------------------- Handler
//	
	@UiHandler("addAuthBt")
	void onAddAuthBtClick(ClickEvent e){
		if(listAllAuth.getSelectedIndex() != -1){
			if(listUserAuth.addEntity(new Auth(foundUser,listAllAuth.getSelectedAppRole()))){
				addUserAuth(listAllAuth.getSelectedAppRole());
			}
		}
	}
	@UiHandler("rmAuthBt")
	void onRmAuthBtClick(ClickEvent e){
		if(listUserAuth.getSelectedIndex() != -1){
//			foundUser.getAuths().remove(new Auth(foundUser,listUserAuth.getItemText(listUserAuth.getSelectedIndex())));
			removeUserAuth(AuthType.valueOf(listUserAuth.getItemText(listUserAuth.getSelectedIndex())));
			listUserAuth.removeItem(listUserAuth.getSelectedIndex());
		}
	}
	@UiHandler("submitBt")
	void onSubmitBtClick(ClickEvent e){
		editUser();
	}
	@UiHandler("searchBt")
	void onSearchBtClick(ClickEvent e){
		searchUser();
	}
	@UiHandler("changePwBt")
	void onChangePwBtClick(ClickEvent e){
		editPw();
	}

	//---------------------------------------------------------------------
	//-------------------------- Server call
	
	private void editUser() {
		if(!checkFormValidity()){
			Window.alert("Invalid form");
			return;
		}
		new ServerCall<Boolean>() {

			@Override
			protected void callService(AsyncCallback<Boolean> asyncCallback) {
				foundUser.setFirstName(firstname.getValue());
				foundUser.setLastName(lastname.getValue());
				foundUser.setEmail(address.getValue());
				foundUser.setPassword(password.getValue());
				foundUser.setEnabled(enabled.getValue());
//				foundUser.setPromotion(promotionLb.getSelectedPromotion());
//				userService.update(foundUser,asyncCallback);
				Window.alert("Call service here !!");
			}

			@Override
			public void onSuccess(Boolean success) {
				if(success)
					new MessagePopupPanel(true,"Succès","L'utilisateur a été édité").show();
				else
					new MessagePopupPanel(false,servicesMessages.operationFailedHeader(),servicesMessages.operationFailed()).show();
			}
		}.call();
	}

	private void searchUser() {
		new ServerCall<User>() {

			@Override
			protected void callService(AsyncCallback<User> asyncCallback) {
				userService.getUser(searchUsername.getText(),asyncCallback);
			}

			@Override
			public void onSuccess(User result) {
				if(result==null)
					Window.alert("User not found");
				else{
					foundUser = result;
					fillUserPanel(result);
				}
			}
		}.call();
	}

	private void addUserAuth(final AuthType auth) {
		Window.alert("Call service here!");
//		new ServerCall<Boolean>() {
//
//			@Override
//			protected void callService(AsyncCallback<Boolean> asyncCallback) {
//				userService.addUserAuth(foundUser, auth, asyncCallback);
//			}
//
//			@Override
//			public void onSuccess(Boolean success) {
//				Window.alert("Success " +success);
//			}
//		}.call();
	}
	
	private void removeUserAuth(final AuthType auth) {
		Window.alert("Call service here!");
//		new ServerCall<Boolean>() {
//
//			@Override
//			protected void callService(AsyncCallback<Boolean> asyncCallback) {
//				userService.removeUserAuth(foundUser, auth, asyncCallback);
//			}
//
//			@Override
//			public void onSuccess(Boolean success) {
//				Window.alert("Success " +success);
//			}
//		}.call();
	}

	private void editPw() {
		if(foundUser==null){
			new MessagePopupPanel(false, "Aucun utilisateur n'est chargé").show();
			return;
		}
		Window.alert("Call service here!");
//		new DialogPopupPanel(new ClassicLabel("Attention cette action est irréversible, voulez-vous continuez ?"),new DialogHandler() {
//			@Override
//			public void onConfirmClick() {
//				
//				final VerticalPanel v = new VerticalPanel();
//				v.setSpacing(5);
//				v.add(new ClassicLabel("Entrez le nouveau mot de passe"));
//				final PasswordTextBox pwdBox = new PasswordTextBox();
//				v.add(pwdBox);
//				new DialogPopupPanel(v,new DialogHandler() {
//					@Override
//					public void onCancelClick() {
//					}
//					@Override
//					public void onConfirmClick() {
//						new ServerCall<Boolean>() {
//
//							@Override
//							protected void callService(AsyncCallback<Boolean> asyncCallback) {
//								userService.changePwd(foundUser,pwdBox.getText(),asyncCallback);
//							}
//
//							@Override
//							public void onSuccess(Boolean result) {
//								new MessagePopupPanel(true, "Le mot de passe a été changé").show();
//							}
//						}.call();
//					}
//				});
//			}
//			@Override
//			public void onCancelClick() {
//			}
//		});
	}
	
	private boolean checkFormValidity() {
		if(username.getText().isEmpty()) return false;
		if(lastname.getText().isEmpty()) return false;
		if(firstname.getText().isEmpty()) return false;
		if(address.getText().isEmpty()) return false;
		return true;
	}
}
